<?php
/**
 * Created by PhpStorm.
 * User: yuanxr
 * Date: 2018/6/10
 * Time: 上午8:33
 */

namespace Utility\Net;
use Utility\IO\File;
use \Exception;
/**********************************************************************************************************************
 * /http：Http访问方法，如get, post, download
 **********************************************************************************************************************/
class Http
{
    private $_File;

    function __construct(){
        $this->_File = new File();
    }

    /**
     * get
     *
     * @param string $url 需要访问的url字符串
     * @return array 返回的数组格式如下：
     * [
     *   'code'=>'http状态码，可以用此码判断是否访问成功',
     *   'body'=>'返回的内容'
     * ]
     */
    public function get(string $url)
    {

        // 设置curl
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    
        // 取值并关闭curl，返回内容
        $content = curl_exec($curl);
        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
            
        // 判断是否失败，如果失败则直接throw new Exception
        if ($code != 200) {
            try{
                throw new Exception("http get返回失败，状态码：$code, url：$url");
            }catch(Exception $e){
                $e->getMessage();
            }
        }
    
        // 返回
        return $content;
    }
    
    /**
     * post
     *
     * @param string $url 需要访问的url字符串
     * @param array $data 需要携带的数据数组
     * @param array $header 需要额外添加的header
     * @return array 返回的数组格式如下：
     * [
     *   'code'=>'http状态码，可以用此码判断是否访问成功',
     *   'body'=>'返回的内容'
     * ]
     */
    public function post(string $url, $data = null, $header = null)
    {
        
        // 设置curl
        if (!$header) {
            $header = ['Content-Type: application/x-www-form-urlencoded'];
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    
        // 取值并关闭curl，返回内容
        $content = curl_exec($curl);
        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
            
        // 判断是否失败，如果失败则直接throw new Exception
        if ($code != 200) {
            try{
                throw new Exception("http post返回失败，状态码：$code, url：$url");
            }catch(Exception $e){
                $e->getMessage();
            }
        }
    
        // 返回
        return $content;
    }
    
    /**
     * download
     *
     * @param string $url 需要下载的文件地址
     * @param string $savedir 需要保存该文件的目录
     * @param string $filename 需要保存该文件的文件名
     * @return boolean 下载成功返回true，否则返回false
     */
    public function download(string $url, string $savedir, string $filename)
    {
    
        // 设置curl
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_NOBODY, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    
        // 取回数据并关闭curl
        $content = curl_exec($curl);
        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $info = curl_getinfo($curl);
        curl_close($curl);
            
        // 如果code不等于200，直接返回false
        if ($code != 200) {
            return false;
        }
    
        // 获取http_file的头部消息和实际内容（header为冗余，以后备用）
        $http_file = array_merge(['body'=>$content], ['header'=>$info]);
    
        // 如果保存目录不存在，则创建
        $this->_File->mkdir($savedir);
    
        // 打开本地文件句柄，并试图写入文件
        $local_file = fopen($savedir . '/' . $filename, 'w');
        if ($local_file) {
    
          // 如果写入成功，关闭本地文件，并返回true
            if (fwrite($local_file, $http_file['body'])) {
                fclose($local_file);
                return true;
            }
        }
    
        // 下载失败返回false
        return false;
    }
}
